﻿using System;
using System.IO;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using Pansoft.Authority.Entities;
using Pansoft.HIME.Tools.AuthorityConfigFileEditor.Nodes;

namespace Pansoft.HIME.Tools.AuthorityConfigFileEditor
{
    public partial class MainForm : Form
    {
        private XmlDocument _Document;
        private int _Id = 601;

        public MainForm()
        {
            InitializeComponent();
            MessageBox.Show("内部开发期使用工具。Bug多多，未做太多人机界面考虑。请操作时谨慎一些。");
            _Tree.ItemHeight = 20;
            _Tree.BeforeCheck += _Tree_BeforeCheck;
        }

        void _Tree_BeforeCheck(object sender, TreeViewCancelEventArgs e)
        {
            var node = (AbstractAuthTreeNode) e.Node;
            node.AuthorityItem.Enable = node.Checked;
        }

        private void AddCategory(object sender, EventArgs e)
        {
            TreeNode node = _Tree.SelectedNode;
            if (node == null)
                return;
            if (node is AuthItemNode)
            {
                MessageBox.Show("权限项下不允许创建分类权限");
                return;
            }
            var item = new AuthorityItem
            {
                DatasetLevel = 0,
                Enable = false,
                Id = _Id
            };
            var form = new AuthorityItemForm(item);
            if (form.ShowDialog(this) == DialogResult.OK)
            {
                node.Nodes.Add(new CategoryNode(form.AuthorityItem));
                _Id++;
                _Tree.ExpandAll();
            }
        }

        private void AddAuthItem(object sender, EventArgs e)
        {
            TreeNode node = _Tree.SelectedNode;
            if (node == null)
                return;
            var item = new AuthorityItem
            {
                DatasetLevel = 0,
                Enable = false,
                Id = _Id
            };
            var form = new AuthorityItemForm(item);
            if (form.ShowDialog(this) == DialogResult.OK)
            {
                node.Nodes.Add(new AuthItemNode(form.AuthorityItem));
                _Id++;
                _Tree.ExpandAll();
            }
        }

        private void RemoveItem(object sender, EventArgs e)
        {
            TreeNode node = _Tree.SelectedNode;
            if (node == null)
                return;
            if (node is RootNode)
            {
                MessageBox.Show("根不允许删除");
                return;
            }
            node.Remove();
            _Tree.ExpandAll();
        }

        private void NewFileButtonClick(object sender, EventArgs e)
        {
            var item = new AuthorityItem
            {
                DatasetLevel = 0,
                Name = "根配置",
                Enable = true,
                Id = 1
            };
            _Tree.Nodes.Add(new RootNode(item));
            _Tree.ExpandAll();
        }

        private void OpenFileButtonClick(object sender, EventArgs e)
        {
            FileDialog dialog = new OpenFileDialog();
            dialog.DefaultExt = ".Xml";
            if(dialog.ShowDialog(this)== DialogResult.OK)
            {
                var document = new XmlDocument();
                try
                {
                    document.Load(dialog.FileName);
                }
                catch (Exception exception)
                {
                    MessageBox.Show(string.Format("打开文档出错，请检查。\r\n{0}", dialog.FileName));
                }
                Parse(document);
            }
        }

        /// <summary>从一个Xml中解析所有权限项列表
        /// </summary>
        public void Parse(XmlDocument document)
        {
            if (document == null)
                throw new ArgumentNullException("document");
            Cursor = Cursors.WaitCursor;
            _Document = document;
            _Tree.Nodes.Clear();

            var authItem = GetAuthItem(document.DocumentElement);
            var rootNode = new RootNode(authItem);
            _Tree.Nodes.Add(rootNode);
            ParseElement(document.DocumentElement, rootNode);
            _Tree.ExpandAll();
            Cursor = Cursors.Default;
        }

        private void ParseElement(XmlNode node, AbstractAuthTreeNode treeNode)
        {
            foreach (XmlNode sNode in node.ChildNodes)
            {
                if (sNode.NodeType != XmlNodeType.Element)
                    continue;
                var element = (XmlElement) sNode;
                if (element.Name != "AUTH")
                    continue;
                var auth = GetAuthItem(element);
                var nodeType = element.GetAttribute("Type");
                AbstractAuthTreeNode subTreeNode;
                switch (nodeType)
                {
                    case "Root":
                        subTreeNode = new RootNode(auth);
                        break;
                    case "Category":
                        subTreeNode = new CategoryNode(auth);
                        break;
                    default:
                        subTreeNode = new AuthItemNode(auth);
                        break;
                }
                treeNode.Nodes.Add(subTreeNode);

                if (element.ChildNodes.Count > 0)
                {
                    ParseElement(element, subTreeNode);
                }
            }
        }

        private static AuthorityItem GetAuthItem(XmlElement element)
        {
            var auth = new AuthorityItem
            {
                Id = Convert.ToInt32(element.GetAttribute("Id")),
                DatasetLevel = Convert.ToInt16(element.GetAttribute("DatasetLevel")),
                Name = element.GetAttribute("Name"),
                Description = element.GetAttribute("Description"),
                Enable = bool.Parse(element.GetAttribute("Enable"))
            };
            return auth;
        }


        private void SaveFileButtonClick(object sender, EventArgs e)
        {
            var root = (RootNode)_Tree.Nodes[0];
            _Document = new XmlDocument();
            _Document.AppendChild(_Document.CreateXmlDeclaration("1.0", "utf-8", ""));
            BuildFile(root, _Document);
            FileDialog dialog = new SaveFileDialog();
            if (dialog.ShowDialog(this) == DialogResult.OK)
            {
                _Document.Save(dialog.FileName);
                MessageBox.Show(string.Format("保存到：{0} ", dialog.FileName));
            }
        }

        private void BuildFile(AbstractAuthTreeNode treeNode, XmlNode xmlNode)
        {
            var authItem = treeNode.AuthorityItem;
            XmlElement ele;
            if(xmlNode is XmlDocument)
                ele = ((XmlDocument)xmlNode).CreateElement("AUTH");
            else
            {
                if (xmlNode.OwnerDocument == null)
                    return;
                ele = xmlNode.OwnerDocument.CreateElement("AUTH");
            }
            var nodeType = "Item";
            if (treeNode is RootNode)
                nodeType = "Root";
            else if (treeNode is CategoryNode)
                nodeType = "Category";
            ele.SetAttribute("Type", nodeType);
            ele.SetAttribute("Id", authItem.Id.ToString());
            ele.SetAttribute("Name", authItem.Name);
            ele.SetAttribute("DatasetLevel", authItem.DatasetLevel.ToString());
            ele.SetAttribute("Enable", authItem.Enable.ToString());
            ele.SetAttribute("Description", authItem.Description);
            xmlNode.AppendChild(ele);
            if(treeNode.Nodes.Count>0)
            {
                foreach (AbstractAuthTreeNode subTreeNode in treeNode.Nodes)
                {
                    BuildFile(subTreeNode, ele);
                }
            }
        }

        private void PrintFileButtonClick(object sender, EventArgs e)
        {

        }
    }
}